package com.onegene.pdf.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.onegene.pdf.component.AbstractReportBuilder;
import com.onegene.pdf.component.config.CommonParam;
import com.onegene.pdf.component.entity.EarlyReportBean;
import com.onegene.pdf.component.entity.LogoImage;
import com.onegene.pdf.component.entity.PdfRequest;
import com.onegene.pdf.component.entity.PrintReportBean;
import com.onegene.pdf.component.factory.ReportBuilderContext;
import com.onegene.pdf.component.factory.ReportFactory;
import com.onegene.pdf.component.report.CommonHandler;
import com.onegene.pdf.entity.Sample;
import com.onegene.pdf.entity.SampleExpand;
import com.onegene.pdf.entity.SampleResult;
import com.onegene.pdf.mapper.SampleExpandMapper;
import com.onegene.pdf.mapper.SampleMapper;
import com.onegene.pdf.service.CommonService;
import com.onegene.pdf.service.DownLoadSerivce;
import com.onegene.pdf.util.PdfUtil;
import com.onegene.pdf.util.StopWatchUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;
import tk.mybatis.mapper.entity.Example;

import java.util.concurrent.CountDownLatch;

/**
 * @author: laoliangliang
 * @description:
 * @create: 2020/7/27 15:48
 **/
@Service
@Slf4j
public class DownLoadSerivceImpl implements DownLoadSerivce {

    @Autowired
    private SampleMapper sampleMapper;

    @Autowired
    private SampleExpandMapper sampleExpandMapper;

    @Autowired
    private CommonParam commonParam;

    @Autowired
    private CommonService commonService;

    @Autowired
    private ApplicationContext applicationContext;

    @Override
    public void saveToDisk(PdfRequest pdfRequest) {
        StopWatchUtil.calculate("总", desc -> {
            int size = pdfRequest.getUuids().size();
            CountDownLatch countDownLatch = new CountDownLatch(size);
            pdfRequest.getUuids().parallelStream().forEach(uuid -> {
                StopWatchUtil.calculate(uuid + ",", d -> {
                    doSaveToDisk(pdfRequest, countDownLatch, uuid);
                });
            });
            try {
                countDownLatch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
    }

    private void doSaveToDisk(PdfRequest pdfRequest, CountDownLatch countDownLatch, String uuid) {
        try {
            SampleResult sampleResult = getSampleResult(uuid);
            if (!sampleResult.vaild()) {
                log.error("uuid:{},参数存在问题：{}", uuid, JSON.toJSONString(sampleResult));
                return;
            }

            //判断不需要再生成则下一条
            if (isOver(pdfRequest, sampleResult)) {
                log.info("跳过uuid:{}", uuid);
                return;
            }

            Integer type = pdfRequest.getType();
            PrintReportBean printReportBean = null;
            EarlyReportBean earlyReportBean = null;
            if (type < 3) {
                printReportBean = commonService.getGeneReportBean(pdfRequest.getToken(), uuid, type);
            } else {
                earlyReportBean = commonService.getEarlyReportBean(pdfRequest.getToken(), uuid, type);
            }
            if (printReportBean == null && earlyReportBean == null) {
                log.error("uuid:{} pdf数据不存在", uuid);
                return;
            }

            // 构建PDF
            this.doBuilderPdf(pdfRequest, sampleResult, printReportBean, earlyReportBean);

            if (pdfRequest.getUpdate()) {
                // pdf状态成功
                updatePdfStateById(sampleResult.getId(), SampleExpand.PdfState.YES);
            }

        } catch (Exception e) {
            log.info("未知异常：", e);
            int size = pdfRequest.getUuids().size();
            for (int i = 0; i < size; i++) {
                countDownLatch.countDown();
            }

            SampleResult sampleResult = getSampleResult(uuid);
            if (pdfRequest.getUpdate()) {
                // pdf状态失败
                updatePdfStateById(sampleResult.getId(), SampleExpand.PdfState.FAIL);
            }
        } finally {
            countDownLatch.countDown();
        }
    }


    private void doBuilderPdf(PdfRequest pdfRequest, SampleResult sampleResult, PrintReportBean printReportBean, EarlyReportBean earlyReportBean) {
        ReportBuilderContext builderContext = new ReportBuilderContext();
        BeanUtil.copyProperties(pdfRequest, builderContext);
        LogoImage logoImage = commonService.getLogoImageUrl(pdfRequest.getLogoCode());
        if (logoImage != null) {
            builderContext.setLogoImageUrl(logoImage.getImageUrl());
            builderContext.setStamperUrl(logoImage.getStamperUrl());
        }
        builderContext.setFontPath(commonParam.fontPath);
        String prefix = PdfUtil.getPrefixPath(commonParam, pdfRequest);
        builderContext.setPrefixPath(prefix);
        builderContext.setOutPath(prefix + "/" + sampleResult.toString() + ".pdf");
        // 用药则查询是成人还是儿童
        Integer version = builderContext.getVersion();
        if (builderContext.getType() == 1) {
            if ("5df9bf0ba9847e7f6faec080".equals(sampleResult.getTemplateRefId())) {
                version = 1;
            } else if ("5cd0d53117dbfa109b6ebcda".equals(sampleResult.getTemplateRefId())) {
                version = 2;
            }
        }
        // 早筛
        Environment environment = applicationContext.getEnvironment();
        String profile = environment.getActiveProfiles()[0];
        if (builderContext.getType() == 3) {
            version = CommonHandler.setPdfVersion(sampleResult, version, profile);
        }
        builderContext.setVersion(version);
        AbstractReportBuilder builder = ReportFactory.create(builderContext);
        if (printReportBean != null) {
            builder.buildAll(printReportBean);
        }
        if (earlyReportBean != null) {
            builder.buildAll(earlyReportBean);
        }
    }



    private boolean isOver(@RequestBody PdfRequest pdfRequest, SampleResult sampleResult) {
        SampleExpand sampleExpandQuery = new SampleExpand();
        sampleExpandQuery.setSampleId(sampleResult.getId());
        SampleExpand sampleExpand = sampleExpandMapper.selectOne(sampleExpandQuery);
        return SampleExpand.PdfState.YES.val().equals(sampleExpand.getPdfState()) && (pdfRequest.getForce() != 1);
    }

    /**
     * 修改pdf状态
     */
    private void updatePdfStateById(Long id, SampleExpand.PdfState pdfState) {
        SampleExpand sampleExpandUpdate = new SampleExpand();
        sampleExpandUpdate.setPdfState(pdfState.val());
        Example example = new Example(SampleExpand.class);
        example.createCriteria().andEqualTo("sampleId", id);
        sampleExpandMapper.updateByExampleSelective(sampleExpandUpdate, example);
    }

    private SampleResult getSampleResult(String uuid) {
        Sample sampleQuery = new Sample();
        sampleQuery.setUuid(uuid);
        return sampleMapper.selectSampleResult(sampleQuery);
    }
}
